﻿/*******************************************************
Copyright © 2007-2009 Active Technologies Group, Inc. (ATGi)

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
*******************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using CommunityServer.Components;
using System.IO;

namespace ATGi.CS.BrightCove
{
    public enum BCVideoEconomics { FREE, AD_SUPPORTED };

    public class BrightCoveVideo : BrightCoveObjectBase
    {
        #region fields
        private string _name;
        private string _shortDescription;
        private string _longDescription;
        private string _linkUrl;
        private string _linkText;
        private List<string> _tags;
        private string _videoStillUrl;
        private string _thumbnailUrl;
        private string _referenceId;
        private long _id;
        private DateTime _creationDate;
        private DateTime _publishedDate;
        private DateTime _lastModifiedDate;
        private long _length;
        private int _playsTotal;
        private int _playsTrailingWeek;
        private BCVideoEconomics _econ;
        private Stream _video;
        #endregion fields

        #region Properties
        // <summary>
        // A number that uniquely identifies this Video, assigned by Brightcove when the Video is created.
        // </summary>
        public long id { get { return _id; }
            set { _id = value; }
        }

        // <summary>
        // The title of this Video.
        // </summary> 
        public String name
        {
            get { return _name; }
            set { _name = value; }
        }

        // <summary>
        // A short description describing this Video, limited to 256 characters.
        // </summary> 
        public String shortDescription
        {
            get { return _shortDescription; }
            set { _shortDescription = value; }
        }

        // <summary>
        // A longer description of this Video, bounded by a 1024 character limit.
        // </summary> 
        public String longDescription
        {
            get { return _longDescription; }
            set { _longDescription = value; }
        }

        // <summary>
        // The date this Video was created, represented as the number of milliseconds since the Unix epoch.
        // </summary> 
        public DateTime creationDate { get { return _creationDate; } }

        // <summary>
        // The date this Video was last made active, represented as the number of milliseconds since the Unix epoch.
        // </summary> 
        public DateTime publishedDate { get { return _publishedDate; } }

        // <summary>
        // The date this Video was last modified, represented as the number of milliseconds since the Unix epoch.
        // </summary> 
        public DateTime lastModifiedDate { get { return _lastModifiedDate; } }

        // <summary>
        // An optional URL to a related item.
        // </summary> 
        public String linkURL
        {
            get { return _linkUrl; }
            set { _linkUrl = value; }
        }

        // <summary>
        // The text displayed for the linkURL.
        // </summary> 
        public String linkText
        {
            get { return _linkText; }
            set { _linkText = value; }
        }

        /// <summary>
        /// The url at bright cove where the video may be viewed.
        /// </summary>
        public string SourceURL
        {
            get { return String.Format(BrightCoveConfiguration.Instance.VideoLinkFormat, BrightCoveConfiguration.Instance.DefaultPlayerID, this.id); }
        }

        // <summary>
        // A list of Strings representing the tags assigned to this Video.
        // </summary> 
        public List<String> tags = new List<string>();

        // <summary>
        // The URL to the video still image associated with this Video. Video stills are 480x360 pixels.
        // </summary> 
        public String videoStillURL
        {
            get { return _videoStillUrl; }
        }

        // <summary>
        // The URL to the thumbnail image associated with this Video. Thumbnails are 120x90 pixels.
        // </summary> 
        public String thumbnailURL
        {
            get { return _thumbnailUrl; }
        }

        // <summary>
        // A user-specified id that uniquely identifies this Video. ReferenceID can be used as a foreign-key to identify this video in another system. 
        // </summary> 
        public String referenceId
        {
            get { return _name; }
            set { _name = value; }
        }

        // <summary>
        // The length of this video in milliseconds.
        // </summary> 
        public long length { get { return _length; } }

        // <summary>
        // Either FREE or AD_SUPPORTED. AD_SUPPORTED means that ad requests are enabled for this Video.
        // </summary> 
        public BCVideoEconomics Economics
        {
            get { return _econ; }
            set { _econ = value; }
        }

        string _flvUrl;
        /// <summary>
        /// The source flash video where public videos may be downloaded in full for offline viewing.
        /// </summary>
        public string FlashDownloadURL
        {
            get { return _flvUrl; }
        }

        // <summary>
        // How many times this Video has been played since its creation.
        // </summary> 
        public int playsTotal { get { return _playsTotal; } }

        // <summary>
        // How many times this Video has been played within the past seven days, exclusive of today.
        // </summary> 
        public int playsTrailingWeek { get { return _playsTrailingWeek; } }
        #endregion Properties

        #region ctor
        // <summary>
        //
        // </summary> 
        public BrightCoveVideo()
        {

        }

        public BrightCoveVideo(JsonReader reader)
        {
            this.Populate(reader);
        }
        #endregion ctor

        public override void Populate(JsonReader reader)
        {
            reader.Read();
            while (reader.TokenType != JsonToken.EndObject)
            {
                if (reader.TokenType == JsonToken.PropertyName)
                {
                    switch (reader.Value.ToString())
                    {
                        case "error":
                            reader.Read();
                            EventLogs.Write(String.Format("Error: {0}", reader.Value), "BrightCove", -80000, EventType.Error);
                            break;

                        case "id":
                            reader.Read();
                            _id = (long)reader.Value;
                            break;

                        case "name":
                            reader.Read();
                            name = (string)reader.Value;
                            break;

                        case "shortDescription":
                            reader.Read();
                            shortDescription = (string)reader.Value;
                            break;

                        case "longDescription":
                            reader.Read();
                            longDescription = (string)reader.Value;
                            break;

                        case "creationDate":
                            reader.Read();
                            _creationDate = DateFromUnix(reader.Value);
                            break;

                        case "publishedDate":
                            reader.Read();
                            _publishedDate = DateFromUnix(reader.Value);
                            break;

                        case "lastModifiedDate":
                            reader.Read();
                            _lastModifiedDate = DateFromUnix(reader.Value);
                            break;

                        case "linkURL":
                            reader.Read();
                            linkURL = (string)reader.Value;
                            break;

                        case "linkText":
                            reader.Read();
                            linkText = (string)reader.Value;
                            break;

                        case "tags":
                            reader.Read();
                            tags.Clear();
                            while (reader.TokenType != JsonToken.EndArray)
                            {
                                reader.Read();
                                if(reader.Value != null)
                                    tags.Add(reader.Value.ToString());
                            }
                            break;
                        case "videoStillURL":
                            reader.Read();
                            _videoStillUrl = (string)reader.Value;
                            break;

                        case "thumbnailURL":
                            reader.Read();
                            _thumbnailUrl = (string)reader.Value;
                            break;

                        case "referenceId":
                            reader.Read();
                            referenceId = (string)reader.Value;
                            break;

                        case "length":
                            reader.Read();
                            _length = (long)reader.Value;
                            break;

                        case "economics":
                            reader.Read();
                            Economics = (BCVideoEconomics)Enum.Parse(typeof(BCVideoEconomics), reader.Value.ToString());
                            break;

                        case "playsTotal":
                            {
                                reader.Read();
                                int parsedValue;
                                if (reader.Value != null && Int32.TryParse(reader.Value.ToString(), out parsedValue))
                                    _playsTotal = parsedValue;
                                break;
                            }
                        case "playsTrailingWeek":
                            {
                                reader.Read();
                                int parsedValue;
                                if (reader.Value != null && Int32.TryParse(reader.Value.ToString(), out parsedValue))
                                    _playsTrailingWeek = parsedValue;
                                break;
                            }
                        case "FLVURL":
                            reader.Read();
                            if(reader.Value != null)
                                _flvUrl = reader.Value.ToString();
                            break;
                        case "FLVFullLength":
                            //JHG: Not in original from brightcove - if objects exist as members, this loop fails too early. 
                            reader.Read();
                            while (reader.TokenType != JsonToken.EndObject)
                            {
                                //JHG: Add sub-object population here if desired.
                                reader.Read();
                            }
                            break;
                        case "renditions":
                            reader.Read();
                            //JHG: Not in original bc source. Read out the entire array
                            while (reader.TokenType != JsonToken.EndArray)
                            {
                                //TODO: parse into array member if desired.
                                reader.Read();
                            }
                            break;
                        default:
                            try
                            {
                                reader.Read();
                            }
                            catch (Newtonsoft.Json.JsonReaderException eJson)
                            {
                                EventLogs.Write("Json read failure in default read. Moving on." + eJson.Message, "JSON", -65001, EventType.Warning);
                                return;
                            }
                            break;
                    }
                }
                try
                {
                    reader.Read();
                }
                catch (Newtonsoft.Json.JsonReaderException eJson)
                {
                    EventLogs.Write("Json read failure in end read. Moving on." + eJson.Message, "JSON", -65001, EventType.Warning);
                    return;
                }
            }
            try
            {
                reader.Read();
            }
            catch (Newtonsoft.Json.JsonReaderException eJson)
            {
                EventLogs.Write("Json read failure in final read. Moving on." + eJson.Message, "JSON", -65001, EventType.Warning);
                return;
            }
        }

        public override BrightCoveObjectType Type
        {
            get { return BrightCoveObjectType.Video; }
        }
    }
}
